1. 1. 关于链接方式的区别
    1. 1.0.1. 动态库的调用链接方式
    2. 1.0.2. 两种调用方式

关于链接方式的区别

动态库的调用链接方式

  • 动态库调用方式可分为两种:

    • 显式调用
    • 隐式调用

两种调用方式

  • 显式调用

    在程序中直接通过动态库装载的方式,对程序中定义的 [函数指针]进行加载和赋值。

    下面是用例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    //定义函数指针 以及变量
    void *functionLib; /* Handle to shared lib file */
    char *dlError; /* Pointer to error string */
    //mag
    int (*NDK_MagOpen)(void);
    int (*NDK_MagClose)(void);
    int (*NDK_MagSwiped)(uchar * psSwiped);
    int (*NDK_MagReadNormal)(char *pszTk1, char *pszTk2, char *pszTk3, int *pnErrorCode);
    // ... 省略N行 ...
    // onload.c
    // 定义了一个加载宏
    #define DLSYM(lib, foo) { \
    dlError = (char *)dlerror(); \
    foo = dlsym( lib , #foo); \
    if( dlError || NULL == foo ){ \
    foo = NULL; \
    nRet -= 1; \
    LOGI("dlsym "#foo" fail:%s,Addr:%x,nRet:%d.",
    dlError, (int)foo, nRet); \
    } \
    else{ \
    LOGI("dlsym "#foo" succ. Addr:%x.", (int)foo); \
    } \
    }; \
    //------- 通过显示加载方式加载库文件 --------------------
    int nRet = 0; /* return codes */
    // libnl_ndk.so
    // libnlposapi.so
    functionLib = dlopen("/system/lib/libabcd.so",RTLD_LAZY);
    dlError = (char *)dlerror();
    LOGI("dlopen libnlposapi.so error:%s", dlError);
    if( functionLib == NULL )
    {
    return (-1000);
    }
    //mag
    DLSYM(functionLib, NDK_MagOpen);
    DLSYM(functionLib, NDK_MagClose);
    DLSYM(functionLib, NDK_MagSwiped);
    DLSYM(functionLib, NDK_MagReadNormal);
    // ... 省略N行 ...

    这时候 在mk文件中可以不需要链接这个库(libabcd.so)就可以调用这个库里面的函数。

    像这样:

    int ret= NDK_MagOpen();
    

    这时NDK头文件中也将函数声明定义为函数指针的方式:

    int (*NDK_MagOpen)();
    
  • 隐式调用

    即通过在mk文件中显示指定需要调用链接的函数库的名称,然后在程序运行的过程中由os系统中的装载器以及链接器来完成函数的装载和链接过程。

    如果一个函数定义在libabcd.so中时,我们需要调用它,就要在Android.mk文件中显示指定调用链接函数库名称:

    LOCAL_LDLIBS += labcd
    

    然后在NDK头文件中声明为函数调用方式(注意区别前面的函数指针的什么方式):

    int NDK_MagOpen();
    

    然后调用方式同函数指针的方式:

    int ret= NDK_MagOpen();